import { Context } from 'koa';
import PlanService from '@/services/PlanService';
import TenantPermissionService from '@/services/TenantPermissionService';
import { validate, commonSchemas } from '@/utils/validator';
import * as response from '@/utils/response';
import { Plan, Permission, PlanPermission, Tenant } from '@/models';
import Joi from 'joi';

/**
 * 套餐控制器
 */
export class PlanController {
  /**
   * 创建套餐
   */
  async create(ctx: Context) {
    const schema = Joi.object({
      name: Joi.string().min(2).max(100).required(),
      description: Joi.string().max(1000),
      features: Joi.object().required(),
      priceMonthly: Joi.number().min(0).required(),
      priceYearly: Joi.number().min(0).required(),
      sortOrder: Joi.number().integer().min(0),
    });

    interface CreatePlanData {
      name: string;
      description?: string;
      features: Record<string, any>;
      priceMonthly: number;
      priceYearly: number;
      sortOrder?: number;
    }

    const data = await validate<CreatePlanData>(ctx.request.body as any, schema);

    const plan = await PlanService.createPlan(data as any);

    response.created(ctx, plan, '套餐创建成功');
  }

  /**
   * 获取套餐详情
   */
  async getById(ctx: Context) {
    const { id } = ctx.params;

    const plan = await PlanService.getPlanById(id);

    if (!plan) {
      return response.notFound(ctx, '套餐不存在');
    }

    response.success(ctx, plan);
  }

  /**
   * 获取套餐列表
   */
  async list(ctx: Context) {
    const schema = Joi.object({
      page: Joi.number().integer().min(1).default(1),
      pageSize: Joi.number().integer().min(1).max(100).default(20),
    });

    const { page, pageSize } = await validate<{ page: number; pageSize: number }>(ctx.query as any, schema);

    const result = await PlanService.listPlans(page, pageSize);

    response.paginated(
      ctx,
      result.data,
      result.pagination.total,
      result.pagination.page,
      result.pagination.pageSize,
    );
  }

  /**
   * 获取激活的套餐
   */
  async listActive(ctx: Context) {
    const plans = await PlanService.listActivePlans();

    response.success(ctx, plans);
  }

  /**
   * 更新套餐
   */
  async update(ctx: Context) {
    const { id } = ctx.params;

    const schema = Joi.object({
      name: Joi.string().min(2).max(100),
      description: Joi.string().max(1000),
      features: Joi.object(),
      priceMonthly: Joi.number().min(0),
      priceYearly: Joi.number().min(0),
      isActive: Joi.boolean(),
      sortOrder: Joi.number().integer().min(0),
    });

    interface UpdatePlanData {
      name?: string;
      description?: string;
      features?: Record<string, any>;
      priceMonthly?: number;
      priceYearly?: number;
      isActive?: boolean;
      sortOrder?: number;
    }

    const data = await validate<UpdatePlanData>(ctx.request.body as any, schema);

    const plan = await PlanService.updatePlan(id, data as any);

    response.success(ctx, plan, '套餐更新成功');
  }

  /**
   * 删除套餐
   */
  async delete(ctx: Context) {
    const { id } = ctx.params;

    await PlanService.deletePlan(id);

    response.success(ctx, null, '套餐已删除');
  }

  /**
   * 获取套餐的权限ID列表
   */
  async getPlanPermissions(ctx: Context) {
    const schema = Joi.object({
      planId: commonSchemas.uuid.required(),
    });

    const params = await validate<{ planId: string }>(ctx.params, schema);

    const plan = await Plan.findByPk(params.planId, {
      include: [
        {
          model: Permission,
          as: 'permissions',
          through: { attributes: [] },
        },
      ],
    });

    if (!plan) {
      return response.notFound(ctx, '套餐不存在');
    }

    // 只返回权限ID数组
    const permissionIds = (plan as any).permissions?.map((p: Permission) => p.id) || [];
    response.success(ctx, permissionIds);
  }

  /**
   * 为套餐分配权限
   */
  async assignPermissions(ctx: Context) {
    const paramsSchema = Joi.object({
      planId: commonSchemas.uuid.required(),
    });

    const bodySchema = Joi.object({
      // 允许混合字符串，后续仅保留 UUID 值
      permissionIds: Joi.array().items(Joi.string()).required(),
    });

    const params = await validate<{ planId: string }>(ctx.params, paramsSchema);
    const data = await validate<{ permissionIds: string[] }>(ctx.request.body, bodySchema);

    // 仅保留有效 UUID，忽略诸如 'company'、'file' 等分组/模块标识
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    const filteredPermissionIds = (data.permissionIds || []).filter((id) => uuidRegex.test(id));

    // 验证套餐存在
    const plan = await Plan.findByPk(params.planId);
    if (!plan) {
      return response.notFound(ctx, '套餐不存在');
    }

    // 验证权限存在且不是系统权限
    if (filteredPermissionIds.length > 0) {
      const permissions = await Permission.findAll({
        where: {
          id: filteredPermissionIds,
          isSystem: false, // 系统权限不能分配给套餐
        },
      });

      if (permissions.length !== filteredPermissionIds.length) {
        ctx.throw(400, '部分权限不存在或为系统权限');
        return;
      }
    }

    // 删除旧的权限分配
    await PlanPermission.destroy({
      where: { planId: params.planId },
    });

    // 创建新的权限分配
    if (filteredPermissionIds.length > 0) {
      const planPermissions = filteredPermissionIds.map(permissionId => ({
        planId: params.planId,
        permissionId,
      }));

      await PlanPermission.bulkCreate(planPermissions);
    }

    // 自动同步权限给所有使用该套餐的租户
    const tenants = await Tenant.findAll({
      where: { planId: params.planId },
    });

    let syncedCount = 0;
    for (const tenant of tenants) {
      try {
        await TenantPermissionService.syncPlanPermissions(tenant.id);
        syncedCount++;
      } catch (error) {
        console.error(`Failed to sync permissions for tenant ${tenant.id}:`, error);
      }
    }

    response.success(
      ctx, 
      { syncedTenants: syncedCount }, 
      `权限分配成功，已同步到 ${syncedCount} 个租户`
    );
  }
}

export default new PlanController();

